// 右键框选
import G6 from "@antv/g6";

const { min, max, abs } = Math;
const RIGHT_BUTTON = 2;

G6.registerBehavior('brush-select-right', {
    getDefaultCfg() {
        return {
            brushStyle: {
                fill: '#EEF6FF',
                fillOpacity: 0.4,
                stroke: '#DDEEFE',
                lineWidth: 1,
                lineDash: [4, 4]
            },
            onSelect: function onSelect() {
            },
            onDeselect: function onDeselect() {
            },
            selectedState: 'selected',
            trigger: 'drag',
            includeEdges: false,
            selectedEdges: [],
            selectedNodes: []
        };
    },
    getEvents() {
        return {
            // mousedown: 'onMouseDown',
            dragstart: 'onMouseDown',
            drag: 'onMouseMove',
            // mousemove: 'onMouseMove',
            dragend: 'onMouseUp',
            // mouseup: 'onMouseUp',
            // 'canvas:click': 'clearStates',
            // 'canvas:contextmenu': 'clearStates'
            // 'canvas:mouseleave': 'onMouseLeave',
            // 'canvas:mouseenter': 'onMouseEnter'
        };
    },
    onMouseDown: function onMouseDown(e) {
        // console.log(e)
        // 如果是dragstart 使用buttons判断，其他则用button判断
        if (e.originalEvent.button === RIGHT_BUTTON || (e.type === 'dragstart' && e.originalEvent.buttons === RIGHT_BUTTON)) {
            // 按在node上面拖动时候不应该是框选
            let item = e.item;
            let brush = this.brush;

            if (item) {
                return;
            }

            if (this.trigger !== 'drag' && !this.keydown) {
                return;
            }

            if (this.selectedNodes && this.selectedNodes.length !== 0) {
                this.clearStates();
            }

            if (!brush) {
                brush = this.createBrush();
            }

            this.originPoint = {
                x: e.canvasX,
                y: e.canvasY
            };
            brush.attr({
                width: 0,
                height: 0
            });
            brush.show();
            this.dragging = true;
        }

    },
    onMouseMove: function onMouseMove(e) {
        if (!this.dragging) {
            return;
        }

        if (this.trigger !== 'drag' && !this.keydown) {
            return;
        }

        this.updateBrush(e);
    },
    onMouseUp: function onMouseUp(e) {
        // console.log(e)
        if (e.originalEvent.button === RIGHT_BUTTON
            || (e.type === 'dragstart' && e.originalEvent.buttons === RIGHT_BUTTON) || e.originalEvent.buttons === 0) {
            // console.log("onMouseUp")
            // let graph = this.graph; // TODO: 触发了 canvas:click 导致 clearStates

            if (!this.brush && !this.dragging) {
                return;
            }

            if (this.trigger !== 'drag' && !this.keydown) {
                return;
            }

            this.brush.remove(true); // remove and destroy

            this.brush = null;
            this.getSelectedNodes(e);
            this.dragging = false;
        }
    },
    clearStates: function clearStates() {
        let _a = this,
            graph = _a.graph,
            selectedState = _a.selectedState;

        let nodes = graph.findAllByState('node', selectedState);
        let edges = graph.findAllByState('edge', selectedState);
        nodes.forEach(function (node) {
            return graph.setItemState(node, selectedState, false);
        });
        edges.forEach(function (edge) {
            return graph.setItemState(edge, selectedState, false);
        });
        this.selectedNodes = [];
        this.selectedEdges = [];

        if (this.onDeselect) {
            this.onDeselect(this.selectedNodes, this.selectedEdges);
        }

        graph.emit('nodeselectchange', {
            selectedItems: {
                nodes: [],
                edges: []
            },
            select: false
        });
    },
    getSelectedNodes: function getSelectedNodes(e) {
        let _this = this;

        let _a = this,
            graph = _a.graph,
            originPoint = _a.originPoint,
            shouldUpdate = _a.shouldUpdate;

        let state = this.selectedState;
        let p1 = {
            x: e.x,
            y: e.y
        };
        let p2 = graph.getPointByCanvas(originPoint.x, originPoint.y);
        let left = min(p1.x, p2.x);
        let right = max(p1.x, p2.x);
        let top = min(p1.y, p2.y);
        let bottom = max(p1.y, p2.y);
        let selectedNodes = [];
        let selectedIds = [];
        graph.getNodes().forEach(function (node) {
            let bbox = node.getBBox();

            if (bbox.centerX >= left && bbox.centerX <= right && bbox.centerY >= top && bbox.centerY <= bottom) {
                if (shouldUpdate(node, 'select')) {
                    selectedNodes.push(node);
                    let model = node.getModel();
                    selectedIds.push(model.id);
                    graph.setItemState(node, state, true);
                }
            }
        });
        let selectedEdges = [];

        if (this.includeEdges) {
            // 选中边，边的source和target都在选中的节点中时才选中
            selectedNodes.forEach(function (node) {
                let edges = node.getOutEdges();
                edges.forEach(function (edge) {
                    let model = edge.getModel();
                    let source = model.source,
                        target = model.target;

                    if (selectedIds.includes(source) && selectedIds.includes(target) && shouldUpdate(edge, 'select')) {
                        selectedEdges.push(edge);
                        graph.setItemState(edge, _this.selectedState, true);
                    }
                });
            });
        }

        this.selectedEdges = selectedEdges;
        this.selectedNodes = selectedNodes;

        if (this.onSelect) {
            this.onSelect(selectedNodes, selectedEdges);
        }

        graph.emit('nodeselectchange', {
            selectedItems: {
                nodes: selectedNodes,
                edges: selectedEdges
            },
            select: true
        });
    },
    // 画框
    createBrush: function createBrush() {
        let self = this;
        let brush = self.graph.get('canvas').addShape('rect', {
            attrs: self.brushStyle,
            capture: false,
            name: 'brush-shape'
        });
        this.brush = brush;
        return brush;
    },
    // 更新框
    updateBrush: function updateBrush(e) {
        let originPoint = this.originPoint;
        this.brush.attr({
            width: abs(e.canvasX - originPoint.x),
            height: abs(e.canvasY - originPoint.y),
            x: min(e.canvasX, originPoint.x),
            y: min(e.canvasY, originPoint.y)
        });
    },
});